package com.logic.modular.game.player.hero.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.logic.comment.util.XsRedisUtils;
import com.logic.config.netty.web.service.MessageService;
import com.comment.pojo.domain.logic.domain.PlayerHero;
import com.logic.modular.game.player.hero.mapper.PlayerHeroMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * 基础服务-游戏账户武将
 *
 * @author cxy
 * @since 2024-07-18 10:48:50
 */
@Slf4j
@Service
public class PlayerHeroBaseServiceImpl extends ServiceImpl<PlayerHeroMapper, PlayerHero> {
    private static final String cacheKey = "player:%d:hero";
    @Resource
    private XsRedisUtils xsRedisUtils;

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  基础查询
    public List<PlayerHero> list(@NotNull(message = "playerId不能为空") Long playerId) {
        List<PlayerHero> playerHeroList = listCache(playerId);
        if (playerHeroList.isEmpty()) {
            playerHeroList =
                    super.list(new LambdaQueryWrapper<PlayerHero>().eq(PlayerHero::getUid, playerId));
            if (!playerHeroList.isEmpty()) {
                for (PlayerHero playerHero : playerHeroList) {
                    savaCache(playerHero);
                }
            }
        }
        return playerHeroList;
    }

    public PlayerHero select(@NotNull Long playerId, @NotNull Long coreWuJiangId) {
        PlayerHero playerHero = selectCache(playerId, coreWuJiangId);
        if (playerHero == null) {
            PlayerHero select = PlayerHero.builder().uid(playerId).coreHeroId(coreWuJiangId).build();
            LambdaQueryWrapper<PlayerHero> wrapper = new LambdaQueryWrapper<>(select);
            playerHero = super.getOne(wrapper);
            if (playerHero != null) {
                if (playerHero.getUid() == 0) {
                    throw new RuntimeException("uid不能为空");
                }
                savaCache(playerHero);
            }
        }
        return playerHero;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  更新插入
    public boolean updateById(PlayerHero entity) {
        Long currentForce = entity.getCurrentForce();
        if (currentForce < 0L) {
            entity.setCurrentForce(0L);
        }

        boolean b = super.updateById(entity);
        if (b) {
            PlayerHero byId = super.getById(entity.getId());
            this.savaCache(byId);
            MessageService.sendMessageToUser(entity.getUid(), MessageService.updateJsonObject("playerHero", entity));
        }
        return b;
    }

    public boolean save(PlayerHero accountHero) {
        boolean save = super.save(accountHero);
        accountHero = super.getById(accountHero.getId());
        savaCache(accountHero);
        return save;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////  缓存部分
    public void savaCache(PlayerHero playerHero) {
        if (playerHero.getUid() == null) {
            throw new RuntimeException("uid不能为空");
        }
        String key1 = String.format(cacheKey, playerHero.getUid());
        String key2 = playerHero.getCoreHeroId().toString();
        xsRedisUtils.hSet(key1, key2, playerHero, 60, TimeUnit.MINUTES);

    }

    public PlayerHero selectCache(
            @NotNull(message = "uid不能为空") Long uid,
            @NotNull(message = "coreHeroId不能为空") Long coreHeroId
    ) {
        String key1 = String.format(cacheKey, uid);
        String key2 = coreHeroId.toString();
        xsRedisUtils.expire(key1, 60, TimeUnit.MINUTES);
        return xsRedisUtils.hGetBean(key1, key2, PlayerHero.class);
    }

    public List<PlayerHero> listCache(
            @NotNull(message = "keyValue1不能为空") Long keyValue1
    ) {
        String key1 = String.format(cacheKey, keyValue1);
        xsRedisUtils.expire(key1, 60, TimeUnit.MINUTES);
        Map<String, PlayerHero> stringPlayerHeroMap = xsRedisUtils.hGetAllBean(key1, PlayerHero.class);
        if (stringPlayerHeroMap == null){
            return new ArrayList<>();
        }
        return new ArrayList<>(stringPlayerHeroMap.values());
    }

}